<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>节拍颜色转盘</title>
        <!-- 使用教程https://picocss.com/docs/forms.html -->
        <link rel="stylesheet" href="../libs/pico.min.css">
        <script src="../libs/TimeFactory.js"></script>
        <script src="../libs/PinyinFactory.js"></script>
        <script src="../libs/SoundFactory.js"></script>
        <script src="../libs/easeljs.js"></script>
        <script src="../libs/moonEaseljs.js"></script>
        <script src="../libs/createui.js"></script>
        <script src="../libs/Tone.js"></script>
        <script src="../libs/ColorManager.js"></script>
        <script src="../libs/Unify.js"></script>
        <script src="../libs/TweenMax.min.js"></script>
        <style>
            :root {
                --primary: #5e35b1;
            }
        </style>
    </head>
	<body>
        <main id="main" class="container">
            <article data-theme="light" style="text-align: center;">
                <h1>节拍器</h1>
                <canvas id="canvasSound"></canvas>
            </article>
            <article data-theme="light" style="text-align: center;">
                <h1>颜色选择器</h1>
                <canvas id="canvasColor"></canvas>
                <div class="grid">
                    <input type="text" id="txtColor1" name="颜色值" placeholder="HEX:" required>
                    <input type="text" id="txtColor2" name="颜色值" placeholder="RBGA:" required>
                </div>
            </article>
            <article data-theme="light" style="text-align: center;">
                <h1>大转盘</h1>
                <canvas id="canvasTurn"></canvas>
            </article>
            <article data-theme="light" style="text-align: center;">
                <h1>计时器与倒计时器</h1>
                <canvas id="canvasTime"></canvas>
            </article>
            <article data-theme="light" style="text-align: center; height:600px;">
                <h1>学习拼音</h1>
                <canvas id="canvasPinyin"></canvas>
            </article>
            <article data-theme="light" style="text-align: center;">
                <h1>摩斯码</h1>
                <canvas id="canvasMorse"></canvas>
            </article>
            <article data-theme="light" style="text-align: center;">
                <h1>调整呼吸</h1>
                <canvas id="canvasBreathe"></canvas>
            </article>
        </main>
        
        <script>
            let width=window.innerWidth*0.75;
            createjs.Ticker.framerate = 30;
            let synth = new Tone.PolySynth(Tone.MembraneSynth).toDestination();
            function playSoundByC(name='C4',time='8n'){
                synth.triggerAttackRelease(name, time);
            }
            //------------节拍器---------------
            initSound();
            function initSound(){
                let synth = new Tone.PolySynth(Tone.Synth).toDestination();
                let canvas = document.getElementById('canvasSound');
                //canvas.style.backgroundColor='#ccc'
                canvas.width=width;
                let wid=canvas.width;
                //console.log(canvas)
               
                var stage = createui.initStage(canvas);

                var synthTime=0;
                var synthPlayer=0;
                var label=new MLabel({label:'50'});
                label.setPos(wid/2-40,80)
                label.getText().color='#000';
                stage.addChild(label);

                var slide=new MSlide({width:canvas.width-30,r:10});
                slide.addEvent(mConst.CHANGE,onSlide);
                slide.value=0.5;
                slide.setPos(0,120);
                stage.addChild(slide);

                var names=['开始','停止'];
                var tabbar=new MTabbar();
                stage.addChild(tabbar);
                tabbar.setPos(wid/2-80,0);
                tabbar.setCallBack((id)=>{synthPlayer=1-synthPlayer})
                for(let i=0;i<names.length;i++){
                    tabbar.addItem(new MButton({label:names[i]}));
                }
                var alphas=[1,0.5,0.2];
                var synthCircles=[];
                for(let i=0;i<alphas.length;i++){
                    var shape=new MShape();
                    shape.dc(30+10*i).alpha=alphas[i];
                    shape.setPos(100,50);
                    stage.addChild(shape);
                    if(i>0){
                        synthCircles.push(shape);
                        shape.scale=0.5;
                    }
                }

                function onSlide(e){
                    synthTime=parseInt(slide.value*180)+40
                    label.setText(synthTime+'每分钟节拍数');
                }
                function playSound(){
                    if(synthPlayer){
                        synth.triggerAttackRelease('A3', 0.001);
                        synthCircles.forEach(a=>{
                            a.scale=1;
                            MTween.to(a,{scale:0.5},200);
                        });
                    }
                    let time=60/synthTime*1000;
                    setTimeout(playSound,time);
                }
                playSound();
            }
            //------------颜色选择器---------------
            initColor();
            function initColor(){
                let color='#34F8E9'
                let txtColor1=document.getElementById('txtColor1');
                let txtColor2=document.getElementById('txtColor2');
                let canvas = document.getElementById('canvasColor');
                let context = canvas.getContext("2d");
                canvas.width=width;
                
                let wid=canvas.width-30
                let stage=createui.initStage(canvas);

                 let colPoint=new MStroke();
                 colPoint.dr(10,22,2,'black');
                 stage.addChild(colPoint);

                 let colPoint2=new MStroke();
                 colPoint2.dr(10,22,2,'black');
                 stage.addChild(colPoint2);

                let box=new MShape();
                box.x=box.y=0;
                box.width=box.height=70;
                box.width=wid;
                stage.addChild(box);


                var slide2=new MSlide({width:wid,r:10});
                slide2.addEvent(mConst.CHANGE,onSlide2);
                slide2.skinBar.visible=false;
                slide2.bar.clear();
                slide2.value=0.5;
                let colors=['#000000',color,'#ffffff'];
                slide2.setPos(0,80);
                slide2.addChild(colPoint2);
                stage.addChild(slide2);

                let ratios=[ 0,0.16,0.33,0.50,0.66,0.83,1]
              
                var slide=new MSlide({width:wid,r:10});
                slide.addEvent(mConst.CHANGE,onSlide);
                slide.skinBar.visible=false;
                slide.bar.clear();
                slide.skinBg.clear();
                slide.skinBg.graphics.beginLinearGradientFill(["#FF3333","#FFFA33","#44FF33","#33FDFF","#334AFF","#FF33FE","#FF3333"],ratios, 0, 0, width, 0)
                slide.skinBg.graphics.drawRoundRectComplex(0,0,wid,20,10,10,10,10);
                slide.value=0.5;
                slide.setPos(0,120);
                slide.addChild(colPoint);
                stage.addChild(slide);
                function onSlide(e){
                    [colPoint.x,colPoint.y]=[slide.bar.x-5,slide.bar.y-11]
                    var x = slide.x+slide.bar.x;
                    var y = slide.y+10;
                    if(slide.x<x&&x<slide.x+slide.width){
                        // 获取像素点信息
                        var pixel = context.getImageData(x, y, 1, 1).data;
                        // 输出像素点的RGBA值
                        //console.log("R:" + pixel[0] + " G:" + pixel[1] + " B:" + pixel[2] + " A:" + pixel[3]);
                        let color=ColorManager.rbgToHex(pixel[0],pixel[1],pixel[2]);
                        let colors=['#000000',color,'#ffffff'];
                        slide2.skinBg.clear();
                        slide2.skinBg.graphics.beginLinearGradientFill(colors, [0,0.5,1], 0, 0, width, 0)
                        slide2.skinBg.graphics.drawRoundRectComplex(0,0,wid,20,10,10,10,10);
                        onSlide2()
                    }
                }
                function onSlide2(e){
                    [colPoint2.x,colPoint2.y]=[slide2.bar.x-5,slide2.bar.y-11];
                    var x = slide2.x+slide2.bar.x;
                    var y = slide2.y+10;
                    if(slide2.x<x&&x<slide2.x+slide2.width){
                        // 获取像素点信息
                        var pixel = context.getImageData(x, y, 1, 1).data;
                        // 输出像素点的RGBA值
                        //console.log("R:" + pixel[0] + " G:" + pixel[1] + " B:" + pixel[2] + " A:" + pixel[3]);
                        let color=ColorManager.rbgToHex(pixel[0],pixel[1],pixel[2]);
                        let cmyk=ColorManager.rgbToCmyk2(pixel[0],pixel[1],pixel[2]);
                        box.dr(box.width,box.height,color)
                        txtColor1.value='HEX:'+color;
                        txtColor2.value='RGBA:'+pixel;
                    }
                }
                box.dr(box.width,box.height,color);
                slide2.skinBg.clear();
                slide2.skinBg.graphics.beginLinearGradientFill(['#000000','#34F8E9','#ffffff'], [0,0.5,1], 0, 0, width, 0)
                slide2.skinBg.graphics.drawRoundRectComplex(0,0,wid,20,10,10,10,10);
            }
            //------------转盘选择器---------------
            initTurn();
            function initTurn(){
                let canvas = document.getElementById('canvasTurn');
                canvas.width=width;
                let wid=canvas.width-30
                let stage=createui.initStage(canvas);

                let bg=new MSprite();
                bg.setPos(wid/2,75);
                //bg.shape.dc(73,'#000000',{s:3,c:'#100F03'});
                stage.addChild(bg);
                let num=6;
                function createTurn(){
                    bg.removeAllChildren();
                    for(let i=0;i<num;i++){
                        let sprite=new MSprite();
                        let [a1,a2]=[0,360/num];
                        a1=Math.PI/180*a1;
                        a2=Math.PI/180*a2;
                        sprite.shape.da(73,a1,a2,(i%2==0?'#1E8F87':'#2AC9BD'))
                        sprite.rotation=360/num*i;
                        let txt=new MLabel({label:parseInt(i+1)});
                        txt.rotation=-sprite.rotation;
                        txt.setPos(30+num*1.5,25-num*0.75)
                        sprite.addChild(txt);
                        sprite.txt=txt;
                        sprite.index=i;
                        bg.addChild(sprite)
                    }
                    bg.addChild((new MShape()).dc(3))
                }
                
                let point=(new MShape()).dp(20,3,'#FFA94C').setPos(bg.x,0)
                stage.addChild(point);
                bg.addEventListener('click',onTurn);
                function onTurn(e){
                    playSoundByC();
                    bg.children.forEach((a)=>{
                        a.scale=1;
                        if(a.txt)a.txt.color='#fff';
                    });
                    var rotation=bg.rotation+Math.random()*360+720;
                    TweenMax.to(bg,4,{rotation:rotation,ease:Expo.easeOut,onComplete:onComplete});
                }

                let sw=wid/3
                var label=new MLabel({label:num,c:'#000'});
                label.setPos(sw/2,30);
                stage.addChild(label);

                var slide=new MSlide({width:sw,r:10});
                slide.addEvent(mConst.CHANGE,onSlide);
                slide.value=0.4;
                slide.setPos(15,60);
                stage.addChild(slide);

                function onSlide(){
                    num=parseInt(slide.value*10)+2;
                    label.text.text=num;
                    createTurn();
                }
                function onComplete(){
                    playSoundByC('C2')
                    let [x,y]=[bg.x,bg.y-30]
                    bg.children.forEach((a)=>{
                        let pt=a.globalToLocal(x, y);//全局坐标转本地坐标
                        if(a.hitTest(pt.x,pt.y)){
                            a.scale=1.03;
                            a.txt.color='#333';
                            console.log(a.index+1)
                        }
                    });
                }
            }
            //------------计时器---------------
            initTime();
            function initTime(){
                let canvas = document.getElementById('canvasTime');
                canvas.width=width;
                let wid=canvas.width-30;
                let stage=createui.initStage(canvas);
                stage.addChild((new MShape()).dr(wid/2,150,'#144E65'))
                stage.addChild((new MShape()).dr(wid/2,150,'#6DD6FF').setPos(wid/2,0))
                let [x,y]=[10,10]
                var label=new MLabel({label:'00:00:00'});
                label.text.font="bold 36px Arial";
                label.setPos(wid/4,y+10);
                stage.addChild(label);
                var names=['开始','停止','重置'];
                var tabbar=new MTabbar();
                stage.addChild(tabbar);
                tabbar.setPos(wid/8,80);
                tabbar.addEvent(mConst.CHANGE,onTime1)
                for(let i=0;i<names.length;i++){
                    tabbar.addItem(new MButton({label:names[i]}));
                }
                let time1=TimeFactory.createUpTime('time1',0,(data)=>{label.text.text=data.show},3);
                time1.stop();
                function onTime1(e){
                    playSoundByC();
                    if(tabbar.index==0){
                        time1.start();
                    }else if(tabbar.index==1){
                        time1.stop();
                    }else{
                        time1.reset(0);
                        label.text.text='00:00:00'
                    }
                }
                
                var label2=new MLabel({label:'00:00:00',c:'black'});
                label2.text.font="bold 36px Arial";
                label2.setPos(wid/2+wid/4,y+10);
                stage.addChild(label2);
                var num=50;
                var names=['开始','停止'];
                var tabbar2=new MTabbar();
                stage.addChild(tabbar2);
                tabbar2.setPos(wid/2+wid/6,110);
                tabbar2.addEvent(mConst.CHANGE,onTime2)
                for(let i=0;i<names.length;i++){
                    tabbar2.addItem(new MButton({label:names[i]}));
                }
                let time2=TimeFactory.createDownTime('time2',0,(data)=>{timeOver(data)},true,3);
                time2.stop();
                function onTime2(e){
                    playSoundByC();
                    if(tabbar2.index==0){
                        time2.reset(num*60);
                        time2.start();
                    }else if(tabbar2.index==1){
                        time2.stop();
                    } 
                }
                var label3=new MLabel({label:num,c:'#000'});
                label3.setPos(wid/2+wid/4,60);
                stage.addChild(label3);

                var sw=wid*0.46;
                var slide=new MSlide({width:sw,r:10});
                slide.addEvent(mConst.CHANGE,onSlide);
                slide.value=0.5;
                slide.setPos(wid/2+20,75);
                stage.addChild(slide);

                function onSlide(){
                    num=parseInt(slide.value*99)+1;
                    label3.text.text=num;
                }
                function timeOver(data){
                    if(label3){
                        label2.text.text=data.show;
                        if(data.value==0){
                            playSoundByC('C6');
                        }
                    }
                }
            }
            //------------学习拼音---------------
            initPinyin();
            function initPinyin(){
                let canvas = document.getElementById('canvasPinyin');
                let height=500;
                canvas.height=height;
                canvas.width=width;
                let stage=createui.initStage(canvas);
                const colors=ColorManager.warnCoolColors([2,3,5,8,11,10,11,9])
                const all=PinyinFactory.all();
                const labels=all.zw;
                let [x,y,xnum,wid,hei]=[10,10,8,0,0];
                wid=width/(xnum+1);
                hei=height/(xnum+8);
                all.sm.push('');//为了对齐加入一个空字符
                draw(all.sm,10,0,0);
                draw(all.ym,10+hei*4,1);
                draw(all.zt,10+hei*8,2);
                //draw(all.sd,10+hei*11,3);
                //draw(['拼音2','删除',''],50+hei*13,4);
                function draw(arr,offy=0,t=0){
                    let color=colors[t];
                    let boxs=[];
                    for(let i=0;i<arr.length;i++){
                        let name=arr[i];
                        let box=new MButton({width:wid,height:hei,label:name});
                        box.setSkinColors(colors[t],colors[5],colors[6])
                        box.name=name;
                        //moonClick(box,onClick);
                        box.callBack=onClick;
                        boxs.push(box);
                        stage.addChild(box);
                    }
                    let label=new MLabel({label:labels[t],c:'black'});
                    label.setLeft();
                    [label.x,label.y]=[x,offy]
                    stage.addChild(label);
                    Unify.displayRank(boxs,xnum,wid/xnum,hei/xnum,x,y+offy)
                    // if(t==4){
                    //     label.textAlign="center";
                    //     label.x=width/2;
                    //     label.text='输入拼音';
                    //     let box=boxs[2];
                    //     box.x=width/2;
                    //     box.name='pinyin'
                    //     this.input=box.text;
                    //     box.bg.graphics.clear();
                    //     let [w,h,r]=[wid*2,hei,10]
                    //     box.bg.graphics.f(color).rr(-w/2,-h/2,w,h,r);
                    //     moonMouse(box,false);
                    // }
                }
                function onClick(e){
                    let name=e.name;
                    if(name){
                        let url='https://ywx620.gitee.io/learn/rec/sound/pinyin/all/$num.mp3';
                        url=url.replace('$num',name);
                        SoundFactory.alone(url);
                    }
                }
                //------------摩斯码---------------
                initMorse();
                function initMorse(){
                    let canvas = document.getElementById('canvasMorse');
                    canvas.width=width;
                    let hei=canvas.height;
                    let wid=canvas.width-30;
                    let stage=createui.initStage(canvas);
                    let btns=[];
                    let names=['','','短按长按','删除']
                    for(let i=0;i<4;i++){
                        let btn=new MButton({width:hei,height:hei,label:names[i]});
                        btn.index=i;
                        btns.push(btn);
                        stage.addChild(btn);
                        if(i==0){
                            btn.addChild((new MShape()).dr(10,10,'white').setPos(hei/2-5,hei/2-5));
                        }else if(i==1){
                            btn.addChild((new MShape()).dr(60,10,'white').setPos(hei/2-30,hei/2-5));
                        }
                        if(i==2){
                            btn.addEvent(mConst.MOUSEDOWN,mouseDown);
                            btn.addEvent(mConst.MOUSEUP,mouseUp);
                        }else{
                            btn.cbDown=onClick;
                        }
                    }
                    Unify.displayRank(btns,4,4,4);
                    let label=new MLabel({label:'',c:'black'});
                    label.setLeft().setPos(hei*4.1,20);
                    stage.addChild(label);
                    let ctime=0;
                    let str='';
                    function onClick(e){
                        clearTimeout(ctime);
                        switch(e.index){
                            case 0:
                                str+='.'
                                playSoundByC('C3','8n')
                                break;
                            case 1:
                                str+='-'
                                playSoundByC('C3','64n')
                                break;
                            case 3:
                                playSoundByC('C2','8n')
                                label.value=label.value.substring(0,label.value.length-1);
                                return;
                                break;
                        }
                        ctime=setTimeout(()=>{
                            let c=Unify.mosi(str,1);
                            label.value+=c;
                            str='';
                        },1000)
                    }
                    function mouseDown(e){
                        TimeFactory.useTime('morse',0)
                        console.log(0,0);
                    }
                    function mouseUp(e){
                        let t=TimeFactory.useTime('morse',1,null,'');
                        console.log(0,t);
                        if(t<200) onClick({index:0});
                        else      onClick({index:1});
                    }
                }
                //------------调整呼吸---------------
                initBreathe();
                function initBreathe(){
                    let canvas = document.getElementById('canvasBreathe');
                    canvas.width=width;
                    //canvas.style.backgroundColor='#000000'
                    let hei=canvas.height;
                    let wid=canvas.width-30;
                    let stage=createui.initStage(canvas);
                    let x=wid/2-75
                    
                    let label=new MLabel({label:'',c:'#2196F3'});
                    label.fontSize=25;
                    label.setLeft();
                    label.setPos(x+200,hei/2);
                    stage.addChild(label);

                    let labTime1=new MLabel({label:'5',c:'#2196F3'});
                    labTime1.fontSize=20;
                    labTime1.setLeft();
                    labTime1.setPos(20,hei/2-40);
                    stage.addChild(labTime1);

                    let labTime2=new MLabel({label:'',c:'#2196F3'});
                    labTime2.fontSize=20;
                    labTime2.setLeft();
                    labTime2.setPos(20,hei/2+40);
                    stage.addChild(labTime2);

                    var slide=new MSlide({width:wid*0.3,r:10});
                    slide.addEvent(mConst.CHANGE,onSlide);
                    slide.setSkinColors('#2196F3','#0D82E1','#7FD4FF');
                    slide.value=0.5;
                    slide.setPos(20,hei/2)
                    stage.addChild(slide);

                    var time=5;

                    stage.addChild(new MSprite().setPos(x+75,hei/2).dc(75,'#2196F3').setAlpha(0.3));
                    let circle=new MSprite().setPos(x+75,hei/2).dc(75,'#2196F3');
                    stage.addChild(circle);
                    
                    var node=new MCircleButton({label:'',radius:75});
                    node.setSkinColors('#2196F3','#118DF2','#0D82E1');
                    node.set({x:x,y:0})
                    var triangle=new MShape().dp(40,3,'white').setPos(75,75);
                    triangle.rotation=90;
                    node.addChild(triangle);
                    stage.addChild(node);
                    node.callBack=onClick;
                    function onClick(e){
                        node.visible=false;
                        startMove();
                        TimeFactory.createDownTime('huxi',time*60,(data)=>{timeOver(data)},true,2);
                    }
                    function startMove(){
                        if(!node.visible){
                            label.value='持续吸气...'
                            label.color='#2196F3';
                            label.alpha=0.2;
                            MTween.timeLine([[0,{type:'to',item:label,data:{alpha:1},time:300}]
                                            ,[4400,{type:'to',item:label,data:{alpha:0.2},time:300}]]);
                            MTween.to(circle,{scaleX:0.1,scaleY:0.1},5000,()=>{
                                label.value='持续呼气...'
                                label.color='#32C037'
                                MTween.to(circle,{scaleX:1,scaleY:1},5000,()=>{startMove();})
                                MTween.timeLine([[0,{type:'to',item:label,data:{alpha:1},time:300}]
                                            ,[4400,{type:'to',item:label,data:{alpha:0.2},time:300}]]);
                            })
                        }else{
                            label.value='';
                            labTime2.value='';
                        }
                    }

                    function onSlide(e){
                        time=Math.ceil(slide.value*9)+1
                        labTime1.value=`呼吸${time}分钟`
                    }
                    function timeOver(data){
                        labTime2.value=data.show;
                        if(data.value==0){
                            node.visible=true;
                        }
                    }
                }
                
            }
            
        </script>
    </body>
</html>